﻿using System;
using System.Diagnostics.Tracing;
using System.Threading;

namespace Sustainalytics.Utils
{
    [EventSource(Name = "Sustainalytics-Insights")]
    public sealed class InsightsEventSource : System.Diagnostics.Tracing.EventSource
    {
        private static Lazy<InsightsEventSource> _lazyLog = new Lazy<InsightsEventSource>(InitLog, LazyThreadSafetyMode.ExecutionAndPublication);

        public static InsightsEventSource Log => _lazyLog.Value;

        [NonEvent]
        private static InsightsEventSource InitLog()
        {
            var log = new InsightsEventSource();
            log.Ping();

            return log;
        }

        [Event(1, Level = EventLevel.LogAlways)]
        public void Ping()
        {
            if (IsEnabled())
            {
                WriteEvent(1);
            }
        }

        [NonEvent]
        public void Exception(Exception ex)
        {
            if (ex != null)
                this.Exception(ex.GetType().ToString(), ex.Message, ex.ToString());
        }

        [Event(2, Level = EventLevel.Error)]
        public void Exception(string exceptionType, string exceptionMessage, string exceptionInformation)
        {
            if (IsEnabled())
                WriteEvent(2, exceptionType, exceptionMessage, exceptionInformation);
        }

        [Event(3, Level = EventLevel.Informational)]
        public void Test(string controllerName, string httpMethod, int statusCode, string reasonPhrase)
        {
            if (IsEnabled())
            {
                WriteEvent(3, controllerName, httpMethod, statusCode, reasonPhrase);
            }
        }

        [Event(4, Level = EventLevel.Informational)]
        public void InOutEvent(string controllerName, string httpMethod, int statusCode, string reasonPhrase)
        {
            if (IsEnabled())
            {
                WriteEvent(4, controllerName, httpMethod, statusCode, reasonPhrase);
            }
        }

        [Event(5, Level = EventLevel.Informational)]
        public void ArgumentsEvent(string key, string value)
        {
            if (IsEnabled())
            {
                WriteEvent(5, key, value);
            }
        }

        [Event(6, Level = EventLevel.Informational)]
        public void OuptputEvent(string outputValue)
        {
            if (IsEnabled())
            {
                WriteEvent(6, outputValue);
            }
        }

        [Event(7, Level = EventLevel.Informational)]
        public void MongoEvent(string className, string dbName, string collectionName, string opName, string args, string result)
        {
            if (IsEnabled())
            {
                WriteEvent(7, className, dbName, collectionName, opName, args, result);
            }
        }

        [Event(8, Level = EventLevel.Informational)]
        public void UploadFiles(string filename, string type, Guid id)
        {
            if (IsEnabled())
            {
                WriteEvent(8, filename, type, id.ToString());
            }
        }

        [Event(9, Level = EventLevel.Informational)]
        public void StartAutoUnpublish(string currentDT, string referenceDT)
        {
            if (IsEnabled())
            {
                WriteEvent(9, currentDT, referenceDT);
            }
        }

        [Event(10, Level = EventLevel.Informational)]
        public void StopAutoUnpublish(string currentDT, string nextRunDT)
        {
            if (IsEnabled())
            {
                WriteEvent(10, currentDT, nextRunDT);
            }
        }
    }
}
